package com.scott.classicthreadmodal.demo2.storage.delegate;

import com.scott.classicthreadmodal.demo2.storage.IStorage;
import com.scott.classicthreadmodal.Product;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class StorageSimple implements IStorage {

    private final int MAX_SIZE = 10;

    /**
     * 存放产品的列表
     */
    private LinkedList<Product> list = new LinkedList<>();

    @Override
    public void produce(int num, String producerName) throws InterruptedException {
        //对list做同步处理
        synchronized (list) {
            while (list.size() + num > MAX_SIZE) {
                //进行阻塞
                list.wait();
                System.out.println(Thread.currentThread().getName() + ":" + producerName + "【要生产的产品数量】:" + num + "【库存量】:"
                        + list.size() + " 暂时不能执行生产任务!");

            }
            // 生产条件满足情况下，生产num个产品
            for (int i = 1; i <= num; ++i) {
                list.add(new Product((int) (Math.random() * 100)));
            }

            System.out.println(Thread.currentThread().getName() + ":" + producerName + "【已经生产产品数】:" + num + " 【现仓储量为】:" + list.size());

            list.notifyAll();

        }
    }

    @Override
    public List<Product> consume(int num, String consumerName) throws InterruptedException {
        // 同步代码段
        synchronized (list) {
            // 如果仓库剩余容量不足
            while (list.size() + num < MAX_SIZE) {
                // 由于条件不满足，阻塞消费
                list.wait();
                System.out.println(Thread.currentThread().getName() + ":" + consumerName + "【要消费的产品数量】:" + num + " 【库存量】:"
                        + list.size() + " 暂时不能执行消费任务!");


            }

            // 生产条件满足情况下，生产num个产品
            List<Product> result = new ArrayList<>();
            for (int i = 1; i <= num; ++i) {
                result.add(list.getFirst());
                list.remove();
            }

            System.out.println(Thread.currentThread().getName() + ":" + consumerName + "【已经生产产品数】:" + num + " 【现仓储量为】:" + list.size());

            list.notifyAll();
            return result;
        }
    }

    @Override
    public int getStock() {
        synchronized (list) {
            return list.size();
        }
    }
}
